package org.lex.dbq.view.template;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.lex.dbq.model.bo.JdbcUrl;
import org.lex.dbq.model.bo.JdbcUrlTemplate;
import org.lex.dbq.model.bo.Variable;
import org.lex.dbq.model.jdbc.template.IJdbcUrlContext;
import org.lex.dbq.model.jdbc.template.JdbcUrlBuilder;
import org.lex.dbq.model.jdbc.template.JdbcUrlContext;
import org.lex.dbq.model.service.TemplateService;

public class JdbcUrlTemplatePane extends Composite {

	public static void main(String[] args) {
		ApplicationWindow app = new ApplicationWindow(null) {
			@Override
			protected Control createContents(Composite parent) {
				new JdbcUrlTemplatePane(parent, ct());
				return parent;
			}

			private JdbcUrlTemplate ct() {
				return TemplateService.getInstance().getAllObjects().iterator().next();
			}
		};
		app.setBlockOnOpen(true);
		app.open();

		Display.getCurrent().dispose();
	}

	private Text url = null;
	private Text user = null;
	private Text password = null;

	private Map<Variable, Text> variables = new HashMap<Variable, Text>();
	private JdbcUrlContext context = null;
	private final JdbcUrlTemplate template;

	public JdbcUrlTemplatePane(Composite parent, JdbcUrlTemplate template) {
		super(parent, SWT.NONE);
		this.context = new JdbcUrlContext(template);
		this.template = template;
		this.initialize(template);
	}

	public JdbcUrl getJdbcUrl() {
		JdbcUrl u = new JdbcUrl();
		u.setUrl(url.getText());
		u.setUser(user.getText());
		u.setPassword(password.getText());
		u.setDriver(template.getDriver());
		return u;
	}

	public IJdbcUrlContext getContext() {
		return context;
	}

	private void initialize(JdbcUrlTemplate template) {
		GridLayout layout = new GridLayout();
		layout.horizontalSpacing = 5;
		layout.makeColumnsEqualWidth = false;
		layout.numColumns = 4;
		layout.verticalSpacing = 11;
		this.setLayout(layout);

		GridData d = null;
		{
			// user
			d = new GridData();
			d.horizontalSpan = 1;
			d.verticalSpan = 1;

			Label label = new Label(this, SWT.NONE);
			label.setText("User");
			label.setLayoutData(d);

			d = new GridData(GridData.FILL_HORIZONTAL);
			d.horizontalSpan = 3;
			d.verticalSpan = 1;
			user = new Text(this, SWT.BORDER);
			user.setLayoutData(d);
		}
		{
			// password
			d = new GridData();
			d.horizontalSpan = 1;
			d.verticalSpan = 1;

			Label label = new Label(this, SWT.NONE);
			label.setText("Password");
			label.setLayoutData(d);

			d = new GridData(GridData.FILL_HORIZONTAL);
			d.horizontalSpan = 3;
			d.verticalSpan = 1;
			password = new Text(this, SWT.BORDER);
			password.setLayoutData(d);
		}
		{
			// driver
			d = new GridData();
			d.horizontalSpan = 1;
			d.verticalSpan = 1;

			Label label = new Label(this, SWT.NONE);
			label.setText("Driver");
			label.setLayoutData(d);

			d = new GridData(GridData.FILL_HORIZONTAL);
			d.horizontalSpan = 3;
			d.verticalSpan = 1;
			Text text = new Text(this, SWT.BORDER | SWT.READ_ONLY);
			text.setText(template.getDriver().getClassName());
			text.setLayoutData(d);
		}
		{
			// url
			d = new GridData();
			d.horizontalSpan = 1;
			d.verticalSpan = 1;

			Label label = new Label(this, SWT.NONE);
			label.setText("URL");
			label.setLayoutData(d);

			d = new GridData(GridData.FILL_HORIZONTAL);
			d.horizontalSpan = 3;
			d.verticalSpan = 1;
			url = new Text(this, SWT.BORDER);
			url.setLayoutData(d);
		}
		{
			// template
			d = new GridData();
			d.horizontalSpan = 1;
			d.verticalSpan = 1;

			Label label = new Label(this, SWT.NONE);
			label.setText("Template");
			label.setLayoutData(d);

			d = new GridData(GridData.FILL_HORIZONTAL);
			d.horizontalSpan = 3;
			d.verticalSpan = 1;
			Text text = new Text(this, SWT.BORDER | SWT.READ_ONLY);
			text.setText(template.getTemplate());
			text.setLayoutData(d);
		}
		if (false == template.getVariables().isEmpty()) {
			// variables
			d = new GridData(GridData.FILL_BOTH);
			d.horizontalSpan = 4;
			d.verticalSpan = 1;

			GridLayout groupLayout = new GridLayout();
			groupLayout.makeColumnsEqualWidth = false;
			groupLayout.numColumns = 2;

			Group group = new Group(this, SWT.SHADOW_ETCHED_IN);
			group.setLayoutData(d);
			group.setLayout(groupLayout);
			group.setText("Variable");
			{
				MyListener lis = new MyListener();
				for (Variable var : template.getVariables()) {
					d = new GridData();
					d.horizontalSpan = 1;
					d.verticalSpan = 1;

					Label label = new Label(group, SWT.NONE);
					String labelText = var.getDisplayName();
					if (var.isRequired()) {
						labelText = labelText + "(*)";
					}
					label.setText(labelText);
					label.setLayoutData(d);

					d = new GridData(GridData.FILL_HORIZONTAL);
					d.horizontalSpan = 1;
					d.verticalSpan = 1;
					int style = SWT.BORDER;
					if (var.isSecret()) {
						style |= SWT.PASSWORD;
					}
					final Text text = new Text(group, style);
					text.setData("org.lex.dbq.text.var", var);
					text.setText(var.getDefaultValue());
					text.setLayoutData(d);
					text.addModifyListener(lis);

					context.setVariableValue(var, var.getDefaultValue());

					variables.put(var, text);
				}
			}
			url.setText(new JdbcUrlBuilder().buildUrl(template, context));
		}
	}

	private class MyListener implements ModifyListener {
		@Override
		public void modifyText(ModifyEvent e) {
			Text source = (Text) e.getSource();
			String val = source.getText();
			Variable var = (Variable) source.getData("org.lex.dbq.text.var");
			// log.debug(var + " --> " + val);

			context.setVariableValue(var, val);
			String newUrl = new JdbcUrlBuilder().buildUrl(template, context);
			// log.info("new url: " + newUrl);
			url.setText(newUrl);
		}
	}
}
